package it.polito.connectedcar.trafficlight;

import java.util.ArrayList;
import java.util.List;

import it.polito.appeal.traci.Logic;
import it.polito.appeal.traci.Phase;
import it.polito.appeal.traci.Program;

/**
 * Thic class wrpas a TrafficLight program information to be used by a running
 * Traffic Light entity to retrieve information about the phases contained in
 * the program
 * 
 * @author Nicola Aresta
 * 
 */
public class ConnectedTLProgram {

	private List<ConnectedTLLogic> logics;

	public ConnectedTLProgram(Program program) {

		logics = new ArrayList<ConnectedTLProgram.ConnectedTLLogic>(
				program.getLogics().length);
		for (Logic logic : program.getLogics()) {
			ConnectedTLLogic connectedTLLogic = new ConnectedTLLogic(logic);
			logics.add(connectedTLLogic);

		}
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (ConnectedTLLogic logic : getLogics()) {
			sb.append("\"logic\": ")
					.append(" current phase: " + logic.getCurrentPhaseIndex())
					.append(" & phases : \n" + logic.getPhases());
		}
		return sb.toString();
	}

	/**
	 * This class models a single Phase in a Traffic Light program.<br/>
	 * Each phase is described by a state and a duration. the state is
	 * represented as a sequence of characters , each of them containing the
	 * current state present on managed lane. In order to know which is the lane
	 * having a certain state , the index of the character in the sequence has
	 * to be used as key in the controlled Links map
	 * 
	 * @author Nicola Aresta
	 * 
	 */
	public class ConnectedTLPhase {
		private int duration;
		private String state;

		public ConnectedTLPhase(Phase phase) {
			this.duration = phase.getDuration();
			this.state = phase.getState().toString();
		}

		public int getDuration() {
			return duration;
		}

		public void setDuration(int duration) {
			this.duration = duration;
		}

		public String getState() {
			return state;
		}

		public void setState(String state) {
			this.state = state;
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			sb.append("phase # : ").append(" duration : " + getDuration())
					.append(" and state : " + state);
			return sb.toString();
		}
	}

	/**
	 * This class models a single logic in a Traffic light's program definition.
	 * For the time being , only one logic is supported by the system. A logic
	 * contains a set of sequentially alternating phases.
	 * 
	 * @author Nicola Aresta
	 * 
	 */
	public class ConnectedTLLogic {
		private int currentPhaseIndex;
		private List<ConnectedTLPhase> phases;

		public ConnectedTLLogic(Logic logic) {

			phases = new ArrayList<ConnectedTLProgram.ConnectedTLPhase>(logic.getPhases().length);
			this.currentPhaseIndex = logic.getCurrentPhaseIndex();
			for (Phase phase : logic.getPhases()) {
				phases.add(new ConnectedTLPhase(phase));
			}
		}

		public int getCurrentPhaseIndex() {
			return currentPhaseIndex;
		}

		public void setCurrentPhaseIndex(int currentPhaseIndex) {
			this.currentPhaseIndex = currentPhaseIndex;
		}

		public List<ConnectedTLPhase> getPhases() {
			return phases;
		}

		public void setPhases(List<ConnectedTLPhase> phases) {
			this.phases = phases;
		}
	}

	public List<ConnectedTLLogic> getLogics() {
		return logics;
	}

	public void setLogics(List<ConnectedTLLogic> logics) {
		this.logics = logics;
	}
}
